# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<stdbool.h>
typedef enum Status{
    success,fail,fatal,range_error
} Status;//success成功，fail失败，fatal致命的错误，range_error越界
typedef int ElemType;
typedef struct Node
{
    ElemType elem;
    struct Node *next;
} Node ,*Ptr;

typedef Ptr *Sqlistptr;
Status List_retrieve(Sqlistptr L,int pos,ElemType *elem);
Status List_locate(Sqlistptr L,ElemType elem, int *pos);
Status List_insert(Sqlistptr L,int pos ,ElemType elem);
Status List_retrieve1(Sqlistptr L,int pos,Ptr *elem);
Status List_remove(Sqlistptr L,int pos);
Status List_init(Sqlistptr L);
Status List_creat(Sqlistptr L,ElemType *data,int length);
void List_print(Sqlistptr L);
void print(Status s);
int main(){
    Node head;
    head.elem=0;
    head.next=NULL;
    Ptr L;
    Status s;
    L = &head;
    L->next=NULL;
    //初始化测试
    s = List_init(&L);
    print(s);
    //创建数据表测试
    int n=0;
    int *data;
    printf("请输入要生成的数据个数\n");
    scanf("%d",&n);
    data = (int *)malloc(sizeof(int)*n);
    for (size_t i = 0; i < n; i++)
    {
        data[i] = i+1;
    }
    s = List_creat(&L,data,n);
    print(s);
    List_print(&L);
    //按位查找测试
    int pos = 0;
    ElemType elem = 0;
    printf("请输入要查找的位置\n");
    scanf("%d",&pos);
    List_retrieve(&L,pos,&elem);
    printf("%d\n",elem);
    //按值查找测试
    printf("请输入要查找的值\n");
    scanf("%d",&elem);
    List_locate(&L,elem,&pos);
    printf("%d\n",pos);
    //插入测试
    printf("请输入要插入的位置\n");
    scanf("%d",&pos);
    printf("请输入要插入的值\n");
    scanf("%d",&elem);
    List_insert(&L,pos,elem);
    List_print(&L);
    //删除测试
    printf("请输入要删除的位置\n");
    scanf("%d",&pos);
    List_remove(&L,pos);
    List_print(&L);
}
Status List_retrieve(Sqlistptr L,int pos,ElemType *elem){
    Status s = range_error;
    Ptr p = (*L)->next;
    int i=1;
    while (i<pos && p)
    {
        i++;
        p=p->next;
    }
    if (i == pos && p)
    {
        s = success;
        *elem = p->elem;
    }
    return s;
}
Status List_retrieve1(Sqlistptr L,int pos,Ptr *elem){
    Status s = range_error;
    Ptr p = (*L)->next;
    int i=1;
    while (i<pos && p)
    {
        i++;
        p=p->next;
    }
    if (i == pos && p)
    {
        s = success;
        *elem = p;
    }
    return s;
}
Status List_locate(Sqlistptr L,ElemType elem,int *pos){
    Status s = range_error;
    Ptr p = (*L)->next;
    int i = 1;
    while (p)
    {
        if (p->elem == elem) break;
        p=p->next;
        i++;
    }
    if(p){
        *pos = i;
        s = success;
    }
    return s;
}
Status List_insert(Sqlistptr L,int pos,ElemType elem){
    Status s;
    Ptr p,t;
    s = List_retrieve1(L,pos-1,&p);
    if (s == success)
    {
        t = (Ptr)malloc(sizeof(Node));
        if (t)
        {
            t->elem = elem;
            t->next = p->next;
            p->next=t;
            s = success;
        }else s = fatal;        
    }else s = range_error;
    return s;
}
Status List_remove(Sqlistptr L,int pos){
    Status s =range_error;
    Ptr p,t;
    s = List_retrieve1(L,pos-1,&p);
    if(s == success){
        t = p->next;
        p->next = t->next;
        free(t);
        t = NULL;
    }
    return s;
}
Status List_init(Sqlistptr L){
    Ptr p = (*L)->next;
    Ptr t;
    Status s = fail;
   while(p)
    {
        t = p;
        p = p->next;
        free(t);
    }
    if (p == NULL)
    {
        (*L)->next=NULL;
        s = success;
    }
    return s;
}
Status List_creat(Sqlistptr L,ElemType *data,int length){
    Status s =fail;
    Ptr p = NULL;
    s = List_init(L);
    if (s == success)
    {
       for (int i = length-1; i >= 0; i--)
       {
        p = (Ptr)malloc(sizeof(Node));
        if (p)
        {
            p->elem = data[i];
            p->next = (*L)->next;
            (*L)->next = p;
        }else{
            s = fail;
            break;
        }
       }
       
    }
    return s;
    
}
void print(Status i){
    switch (i)
    {
    case 0:
        printf("success\n");
        break;
    case 1:
        printf("fail\n");
        break;
    case 2:
        printf("fatal\n");
        break;
    case 3:
        printf("range_error\n");
        break;
    default:
        break;
    }
}
void List_print(Sqlistptr L){
    Ptr p = (*L)->next;
    while (p)
    {
       printf("%d ",p->elem);
       p=p->next;
    } 
    printf("\n");
}
